import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;


public class DebugLocalization {
    private static Path SRC_Dir = Paths.get("D:", "temp", "SRC_DIR");
    private static Path DEST_Dir = Paths.get("D:", "temp", "DEST_DIR");
    private static Path foutput = Paths.get("D:", "temp", "debug1.txt"); 
    private static Path fsample = Paths.get("D:", "temp", "sample.properties"); 

    public static void main(String[] args) throws Exception {
        init();
        final String pattern = ">[^<>]+<";
        final String exclude_pattern = "(>class=\"tabs-selected\"<)|(>[ ]+<)|(>[$][{][^<>]*[}]<)|(>[a-zA-Z$ -/:?{}0-9.·]+<)";
        //遍历SRC_Dir目录的每个文件，用readFile()函数提取样本库
        Files.walkFileTree(SRC_Dir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException
            {
                try {
                    readFile(file, pattern, exclude_pattern, foutput);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return FileVisitResult.CONTINUE;
            }
        });
        //初始化sample样本库，使用sample.properties
//        Map<String, String> sample = getSample(fsample);
//        updateAllKeyToAllFile(sample, SRC_Dir, DEST_Dir);
    }
    
    private static void init() throws IOException{
        Files.deleteIfExists(foutput);
        Files.deleteIfExists(DEST_Dir);
        Files.copy(SRC_Dir, DEST_Dir);
        
    }
    
    //从文件获取sample样本库
    private static Map<String, String> getSample(Path samplePFile) throws IOException{
        Map<String, String> sample = new HashMap<String, String>();
        BufferedReader br = Files.newBufferedReader(samplePFile, StandardCharsets.UTF_8);
        String line = null;
        while ((line = br.readLine()) != null) {
              String tmp[] = StringUtils.split(line, "=");
              sample.put(tmp[0], tmp[1]);
        }
        br.close();
        return sample;
    }
    
    //str如果包含regex正则表达式能匹配的字符串，则返回true
    private static boolean containsRegex(String str, String regex) throws MalformedPatternException{
        PatternMatcherInput matcherInput = new PatternMatcherInput(str);
        Pattern pattern = new Perl5Compiler().compile(regex);
        return new Perl5Matcher().contains(matcherInput, pattern);
    }
    
    //提前fin文件中的样本，输出到output文件末尾
    private static void readFile(Path fin, String pattern, String exclude_pattern, Path output) throws Exception {
        BufferedReader br = Files.newBufferedReader(fin, StandardCharsets.UTF_8);
        String line = null;
        int n = 0;
        while ((line = br.readLine()) != null) {
            n++;
            Pattern p = new Perl5Compiler().compile(pattern);
            Perl5Matcher matcher = new Perl5Matcher();
            PatternMatcherInput matcherInput = new PatternMatcherInput(line);
            while (matcher.contains(matcherInput, p)) {
                MatchResult result = matcher.getMatch();
                if (containsRegex(result.toString(), exclude_pattern)) {
                    continue;
                }
//                System.out.println(result.toString() + " , " + fin.toString() + " , Line:" + n);
                writeToEnd(output, result.toString() + " , " + fin.toString() + " , Line:" + n);
//                writeToEnd(fsample, result.toString() + "=" + result.toString());
            }
        }
        br.close();
    }
    
    //key 为已提取的翻译前标识，value为对应的翻译结果，用整个sample挨个处理文件，使翻译，destDir为要生成结果的目标目录
    private static void updateAllKeyToAllFile(final Map<String, String> sample, final Path srcDir, final Path destDir) throws Exception {
        Files.walkFileTree(srcDir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException
            {
                Path destFile = Paths.get(destDir.toString(), file.getFileName().toString());
                if(Files.notExists(destFile)){
                    Files.createFile(destFile);
                }
                BufferedReader br = Files.newBufferedReader(file, StandardCharsets.UTF_8);
                BufferedWriter bw = Files.newBufferedWriter(destFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
                String line = null;
                while ((line = br.readLine()) != null) {
                    line = updateAllKeyInStr(line, sample);
                    bw.write(line);
                    bw.newLine();
                }
                bw.close();
                br.close();
                return FileVisitResult.CONTINUE;
            }
        });
    }
    //key 为已提取的翻译前标识，value为对应的翻译结果，用整个sample挨个处理str，使被翻译
    private static String updateAllKeyInStr(String str, Map<String, String> sample) {
        String result = str;
        for (Entry<String, String> entry : sample.entrySet()) {
            result =  StringUtils.replace(result, entry.getKey(), entry.getValue());
        }
        return result;
    }
    
    private static void writeToEnd(Path fot, String msg) throws IOException{
        if(Files.notExists(fot)){
            Files.createFile(fot);
        }
        BufferedWriter bw = Files.newBufferedWriter(fot, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
        bw.write(msg);
        bw.newLine();
        bw.close();
    }

}
